iT邦幫忙

2023 iThome 鐵人賽

DAY 26
0
Software Development

當rust 遇上 cqrs & es系列 第 26

D26 impl upcaster

  • 分享至 

  • xImage
  •  

upcaster用來把舊版本event映射為新版本,有很多種不同實作方式,比如一版一版跳:1 -> 2 -> 3 ... -> 10;或是直接跳:1 -> 10, 2 -> 10, ...,各有不同的成本,在這先實作mapping到當前版本。

#[derive(Debug, Clone, Default)]
pub struct BookEventUpcaster;

impl EventUpcaster for BookEventUpcaster {
    fn can_upcast(&self, event_type: &str, event_version: &str) -> bool {
        true    // 實際要依案例及應用情景,這裡先簡單帶過
    }

    fn upcast(&self, event: SerializedEvent) -> SerializedEvent {
        println!("BookEventUpcaster: {:#?}", event);
        let mut event_upcasted = event.clone();
        match event.event_type.as_str() {
            "BookEvent" => {
                let mut payload = event.payload.clone();
                // 取得 BookEvent::BookCreated 內容
                let mut book_created = payload.get_mut("BookCreated");
                if book_created.is_none() { return event_upcasted; }
                let book_created = book_created.unwrap().as_object_mut().unwrap();
                book_created.insert("author".to_string(), None::<String>.into());
                event_upcasted.payload = payload;
            }
            _ => {}
        }

        event_upcasted
    }
}

因為序列化Enum會帶Enum的選項,而在解析時險能當Json去parse,因為以SerializedEvent來說不知道具體的Event (struct/enum)為何。

SerializedEvent {
    aggregate_id: "test-book-1",
    sequence: 1,
    aggregate_type: "Book",
    event_type: "BookEvent",
    event_version: "0.1.0",
    payload: Object {
        "BookCreated": Object {
            "description": String("使用rust,併同cqrs框架,實現event sourcing"),
            "id": String("test-book-1"),
            "isbn10": String("1234567890"),
            "title": String("Rust 語言開發實戰"),
        },
    },
    metadata: Object {},
}

事件更新需要依不同的版本對應,如果比較複雜的情境,感覺還是需要先準備一個實際的enum / struct,把舊版的JSON值對應好後,再把這個enum / struct序列化為 payload。


上一篇
D25 new version of domain event
下一篇
D27 past events in sourcing
系列文
當rust 遇上 cqrs & es30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言